<template>
  <div id="Roles">
    <!-- 面包屑区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片区域 -->
    <el-card>
      <el-button class="add_button" type="primary" size="small" @click="AddUserClick">添加角色</el-button>
      <!-- 角色列表 -->
      <el-table
        :data="RolesListData"
        border
        stripe
        size="small"
        style="width: 100%"
        :highlight-current-row="true"
      >
        <!-- 展开列 -->
        <el-table-column type="expand" width="50" align="center">
          <template slot-scope="scope">
            <el-row v-for="(frist, index) in scope.row.children" :key="frist.id" :class="['dbbottom',index === 0?'bdtop':'', 'vcenter']">
              <!-- 一级权限 -->
              <el-col :span="6">
                <el-tag effect="dark" size="small" closable @close="RomverTagBayid(scope.row, frist)">{{ frist.authName }}</el-tag>
                <i class="el-icon-caret-right" />
              </el-col>
              <!-- 二级权限 三级权限-->
              <el-col :span="18">
                <!-- 通过for循环嵌套获取二级权限 -->
                <el-row v-for="(twoitem, index2) in frist.children" :key="twoitem.id" :class="[index2 !== 0?'bdtop':'','vcenter']">
                  <!-- 二级权限-->
                  <el-col :span="6">
                    <el-tag effect="dark" size="small" type="danger" closable @close="RomverTagBayid(scope.row, twoitem)">{{ twoitem.authName }}</el-tag>
                    <i class="el-icon-caret-right" />
                  </el-col>
                  <!-- 三级权限 -->
                  <el-col :span="18">
                    <el-tag v-for="(item, index3) in twoitem.children" :key="item.id" :class="index3 !== 0?'bdtop':''" effect="dark" size="small" type="warning" :disable-transitions="true" closable @close="RomverTagBayid(scope.row, item)">{{ item.authName }}</el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column label="#" type="index" width="50" align="center" />
        <el-table-column label="角色名称" prop="roleName" align="center" />
        <el-table-column label="角色描述" prop="roleDesc" align="center" />
        <el-table-column label="操作" align="center">
          <template slot-scope="scope">
            <el-tooltip effect="dark" content="编辑" placement="top" :enterable="false">
              <el-button size="mini" type="primary" icon="el-icon-edit" @click="EditData(scope.row)" />
            </el-tooltip>
            <el-tooltip effect="dark" content="删除" placement="top" :enterable="false">
              <el-button size="mini" type="danger" icon="el-icon-delete" @click="DeleteData(scope.row, scope.$index)" />
            </el-tooltip>
            <el-tooltip effect="dark" content="分配权限" placement="top" :enterable="false">
              <el-button size="mini" type="warning" icon="el-icon-setting" @click="ToolsData(scope.row)" />
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 添加角色 -->
    <el-dialog
      title="添加角色"
      :visible.sync="AddUserDialog"
      width="50%"
      :close-on-click-modal="false"
      @close="AddUserDialogClose"
    >
      <el-form
        ref="AddFormRef"
        :model="AddForm"
        :rules="AddFormRules"
        label-width="100px"
        class="demo-ruleForm"
        size="small"
        :close-on-click-modal="false"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="AddForm.roleName" maxlength="10" minlength="1" placeholder="请输入角色名称" clearable />
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="AddForm.roleDesc" maxlength="200" placeholder="请输入角色描述" clearable />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="mini" @click="AddUserDialog = false">取 消</el-button>
        <el-button size="mini" type="primary" @click="AddUser">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 添加角色END -->

    <!-- 编辑角色 -->
    <el-dialog
      title="编辑角色"
      :visible.sync="EidtUserDialog"
      width="50%"
      :close-on-click-modal="false"
      @close="EidtUserDialogClose"
    >
      <el-form
        ref="EidtFormRef"
        :model="EidtForm"
        :rules="EidtFormRules"
        label-width="100px"
        class="demo-ruleForm"
        size="small"
        :close-on-click-modal="false"
      >
        <el-form-item label="角色名称">
          <el-input v-model="EidtForm.roleName" disabled maxlength="10" minlength="1" placeholder="请输入角色名称" clearable />
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="EidtForm.roleDesc" maxlength="200" placeholder="请输入角色描述" clearable />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="mini" @click="EidtUserDialog = false">取 消</el-button>
        <el-button size="mini" type="primary" @click="EidtUser">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 编辑角色END -->
    <!-- 分配权限 -->
    <el-dialog
      title="分配权限"
      :visible.sync="ToolsDialog"
      width="50%"
      :close-on-click-modal="false"
      @close="ToolsDialogClose"
    >
      <el-tree
        ref="TreeRef"
        :data="ToolsList"
        :props="defaultProps"
        show-checkbox
        node-key="id"
        :default-expand-all="true"
        :default-checked-keys="DefKeys"
      />
      <span slot="footer" class="dialog-footer">
        <el-button size="mini" @click="ToolsDialog = false">取 消</el-button>
        <el-button size="mini" type="primary" @click="ToolsDialogOk">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 分配权限END -->
  </div>
</template>

<script>
export default {
  name: 'Roles',
  data() {
    return {
      RolesListData: [], // 角色列表
      AddUserDialog: false, // 添加弹窗
      AddForm: {
        roleName: '', // 角色名称
        roleDesc: '' // 角色描述
      },
      EidtUserDialog: false, // 编辑弹窗
      EidtForm: {
        id: '',
        roleName: '', // 角色名称
        roleDesc: '' // 角色描述
      },
      // 添加角色验证
      AddFormRules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' },
          { min: 1, max: 10, message: '角色角色的长度在 1 到 10 个字符', trigger: 'blur' }
        ]
      },
      // 权限分配弹窗
      ToolsDialog: false,
      ToolsList: [], // 所有权限树
      defaultProps: { // 树形控件规则
        children: 'children',
        label: 'authName'
      },
      // 树形结构默认勾选
      DefKeys: [],
      // 权限分配的父id
      roleId: '',
      // 编辑用户验证
      EidtFormRules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' },
          { min: 1, max: 10, message: '角色角色的长度在 1 到 10 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  /* HTML DOM加载后马上执行的，如赋值*/
  computed: {},

  /* 观察Vue实例上的数据变动 */
  watch: {},

  /* 模板渲染成html前调用，即通常初始化某些属性值，然后再渲染成视图 */
  created() {
    this.GetRolesListData()
  },

  /* 模板渲染成html后调用，通常是初始化页面完成后，再对html的dom节点进行一些需要的操作 */
  mounted() {},

  /* methods则必须要有一定的触发条件才能执行 */
  methods: {
    // 获取列表数据1.5.1
    async GetRolesListData() {
      const { data: resData } = await this.$http.get('roles')
      if (resData.meta.status !== 200) {
        this.$message.error(resData.meta.msg)
      } else {
        console.log('获取列表数据', resData)
        this.RolesListData = resData.data
      }
    },
    // 根据id删除对应权限1.5.7roles/:roleId/rights/:rightId
    async RomverTagBayid(roleId, rightId) {
      // 弹框
      const confirmResult = await this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      if (confirmResult === 'confirm') {
        const { data: resData } = await this.$http.delete('roles/' + roleId.id + '/rights/' + rightId.id)
        if (resData.meta.status !== 200) {
          this.$message.error(resData.meta.msg)
        } else {
          this.$message.success(resData.meta.msg)
          // this.GetRolesListData()
          roleId.children = resData.data
        }
      } else {
        return this.$message.error('角色已取消删除')
      }
    },
    // 添加角色
    AddUserClick() {
      console.log('添加角色')
      this.AddUserDialog = true
    },
    // 监听对话框关闭事件
    AddUserDialogClose() {
      this.AddForm = {
        roleName: '', // 角色名称
        roleDesc: '' // 角色描述
      }
      this.$refs.AddFormRef.resetFields()
    },
    // 编辑1.5.3
    async EditData(EditData) {
      console.log('编辑弹窗', EditData)
      const { data: resData } = await this.$http.get('roles/' + EditData.id)
      console.log('根据 ID 查询用户信息', resData)
      if (resData.meta.status !== 200) {
        this.$message.error(resData.meta.msg)
      } else {
        this.EidtForm = resData.data
      }
      this.EidtUserDialog = true
    },
    // 编辑确定1.5.4
    EidtUser() {
      console.log('this.EidtForm', this.EidtForm)
      this.$refs.EidtFormRef.validate(async valid => {
        if (valid) {
          const { data: resData } = await this.$http.put('roles/' + this.EidtForm.roleId, {
            roleName: this.EidtForm.roleName,
            roleDesc: this.EidtForm.roleDesc
          })
          if (resData.meta.status !== 200) {
            this.$message.error(resData.meta.msg)
          } else {
            this.$message.success('修改成功')
            this.EidtUserDialog = false
            this.GetRolesListData()
          }
        } else {
          return false
        }
      })
    },
    // 监听编辑对话框关闭
    EidtUserDialogClose() {
      this.$refs.EidtFormRef.resetFields()
    },
    // 监听权限分配对话框关闭
    ToolsDialogClose() {
      console.log('监听权限分配对话框关闭')
      this.DefKeys = []
    },
    // 添加确定1.5.2
    AddUser() {
      this.$refs.AddFormRef.validate(async valid => {
        if (valid) {
          const { data: resData } = await this.$http.post('roles', this.AddForm)
          if (resData.meta.status !== 201) {
            this.$message.error(resData.meta.msg)
          } else {
            this.$message.success('添加成功')
            this.AddUserDialog = false
            this.GetRolesListData()
          }
        } else {
          return false
        }
      })
    },
    // 删除1.5.5
    async DeleteData(DeleteData, index) {
      console.log('删除', DeleteData, index)
      const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      // 数据保护机制（前两条无法删除，利用index>=1[从0开始]来判断）
      if (index > 1) {
        // 如果用户点击确定（确定删除） 返回confirm 否则(取消删除)返回cancel
        if (confirmResult === 'confirm') {
          const { data: resData } = await this.$http.delete('roles/' + DeleteData.id)
          if (resData.meta.status !== 200) {
            this.$message.error(resData.meta.msg)
          } else {
            this.$message.success(resData.meta.msg)
            this.GetRolesListData()
          }
        } else {
          return this.$message.error('用户已取消删除')
        }
      } else {
        return this.$message.error('触发数据保护，表格前两条无法删除')
      }
    },
    // 权限分配获取权限
    async ToolsData(ToolsData) {
      console.log('权限分配获取权限', ToolsData)
      this.roleId = ToolsData.id
      // 获取所有权限数据1.4.1
      const { data: resData } = await this.$http.get('rights/' + 'tree')
      if (resData.meta.status !== 200) {
        this.$message.error(resData.meta.msg)
      } else {
        this.ToolsList = resData.data
        console.log('this.ToolsList', this.ToolsList)
      }
      this.GetLeafKeys(ToolsData, this.DefKeys) // 递归获取三级节点id
      this.ToolsDialog = true
    },
    // 权限分配确定
    async ToolsDialogOk() {
      console.log('权限分配确定')
      const Keys = [
        // 被选中的节点
        ...this.$refs.TreeRef.getCheckedKeys(),
        // 半选中的节点
        ...this.$refs.TreeRef.getHalfCheckedKeys()
      ]
      const IdStr = Keys.join(',')
      console.log('Keys', IdStr)
      const { data: resData } = await this.$http.post('roles/' + this.roleId + '/rights/', { rids: IdStr })
      if (resData.meta.status !== 200) {
        this.$message.error(resData.meta.msg)
      } else {
        this.$message.success('分配成功')
        this.ToolsDialog = false
        this.GetRolesListData()
      }
    },
    // 通过递归的形式，获取角色下所有三级权限，并保存至 DefKeys数组中
    GetLeafKeys(Node, DataArr) {
      // 判断是否包含了children, 如果不包含则是三级节点
      if (!Node.children) {
        return DataArr.push(Node.id)
      }
      // 递归
      Node.children.forEach(item => {
        this.GetLeafKeys(item, DataArr)
      })
    }
  }
}
</script>

<style style lang='scss' scoped>
#Roles{
  .add_button{
    margin-bottom: 20px;
  }
  .el-tag{
    margin: 10px;
  }
  .bdtop{
    border-top: 1px solid #ebeef5;
  }
  .dbbottom{
    border-bottom: 1px solid #ebeef5;
  }
  .vcenter{
    display: flex;
    align-items: center;
  }
}
</style>
